package net.wxxr.http.request;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.Set;

import net.wxxr.dataparse.model.HttpCode;
import net.wxxr.http.config.HttpConnectConfig;
import net.wxxr.http.config.HttpContans;
import net.wxxr.http.model.pojo.HttpResult;
import net.wxxr.http.util.CodeUtil;

import oauth.signpost.http.HttpParameters;

import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.entity.AbstractHttpEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.ByteArrayBuffer;

public class HttpPostCookieOut {

	private static HttpPostCookieOut  instance;
	private HttpPostCookieOut(){};
	 HttpBaseRequest	baseRequest= null;
	 HttpPost  httpPost = null;
	public static synchronized HttpPostCookieOut getInstance(){
		if(null == instance){
			instance = new HttpPostCookieOut();
		}
		return instance;
	}
	//代理服务器
	private HttpHost httpHost;
	private HttpResult httpResult;
	public HttpHost getHttpHost() {
		return httpHost;
	}

	public void setHttpHost(HttpHost httpHost) {
		this.httpHost = httpHost;
	}
	HttpClient httpClient = null;
	
	public  HttpResult getResultCookieOut(HttpBaseRequest	request,HttpResult result){
		this.baseRequest = request;
		this.httpResult = result;
		HttpCode code;
		InputStream entityStream = null;
		try{
		 code = request.prepareRequest();
		if (code != HttpCode.STATUS_OK) {
			result.setResultCode(code);
			return result;
		}
		
		
		initHttpPost();
		addRequestHeaders();
		setRequestParams();
		
		//执行：发起网络请求
		httpClient = getHttpClient();
		HttpResponse httpResponse = httpClient.execute(httpPost);
		int responseCode = httpResponse.getStatusLine().getStatusCode();
		if(baseRequest.isDebug()){
			System.out.println("########## HttpPostCookieOut 正确网络返回码范围[200,300)##########responseCode = " + responseCode);
		}
		
		if (responseCode >= 200 && responseCode < 300) {
			code = HttpCode.STATUS_OK;
			httpResult.setResultCode(code);
		}else if(responseCode == 599){//cookie超时(错误号码 ： 599)
			code = HttpCode.COOKIE_OUT;
			httpResult.setResultCode(code);
		}else if(responseCode == -4){//登录失败
			code = HttpCode.FOUCE_LOGOUT;
			httpResult.setResultCode(code);
		} else {
			code = HttpCode.ERROR_NET_ACCESS;//网络连接错误
			httpResult.setResultCode(code);
		}
		
		//获取返回结果
		byte[] data = new byte[4096];
		ByteArrayBuffer byteBuf = new ByteArrayBuffer(4096);
		entityStream = httpResponse.getEntity().getContent();
		while (!baseRequest.isCancel()) {
			int bytesRead = entityStream.read(data);
			if (bytesRead == -1) {
				break;
			}
			byteBuf.append(data, 0, bytesRead);
		}

		byte[] retData = null;
		if (baseRequest.isGzip()) {//解压数据
			retData = CodeUtil.gzipDecoder(byteBuf.toByteArray());
			httpResult.setData(retData);
		} else {
			retData = byteBuf.toByteArray();
			httpResult.setData(retData);
		}
		//设置并保持请求响应的报文头信息
		
		
		if(retData != null) {
			if(baseRequest.isDebug()) {
				System.out.println(new String("11############# HttpPostCookieOut  服务器响应结果数据 byte[]############ = " + retData.toString()));
			}
		}
		
		
	} catch (Exception e) {
		code = HttpCode.ERROR_NET_ACCESS;
		httpResult.setResultCode(code);
	} catch (OutOfMemoryError e) {
		code = HttpCode.ERROR_NET_ACCESS;
		httpResult.setResultCode(code);
	} finally {
		if (entityStream != null) {
			try {
				entityStream.close();
			} catch (IOException e) {
				code = HttpCode.ERROR_NET_ACCESS;
				httpResult.setResultCode(code);
			}
		}
		if (httpClient != null) {
			ClientConnectionManager ccm = httpClient.getConnectionManager();
			if (ccm != null) {
				ccm.closeExpiredConnections();
			}
		}
	}
		return httpResult;
	}
	
	private  void initHttpPost() {
		httpPost = new HttpPost(baseRequest.getUrl());
	}
	private void addRequestHeaders() {
		//动态添加消息头
		if (baseRequest.isGzip()) {
			httpPost.setHeader("Accept-Encoding", "gzip,deflate");
		}
		//处理以回调方式静态的加载公用消息头(查看TaskManagerTemp.java的静态代码块)
		if (baseRequest.getHeadParams() != null) {
			Iterator<String> iterator = baseRequest.getHeadParams().keySet().iterator();
			while (iterator.hasNext()) {
				String key = iterator.next();
				String value = baseRequest.getHeadParams().getFirst(key);
				httpPost.addHeader(key, value);
			}
		}
	}
	
	private void setRequestParams()throws Exception{
		AbstractHttpEntity entity = null;
		HttpPostRequest postRequest = (HttpPostRequest)baseRequest;
		String contentType = postRequest.getContentType();
		String entityString = null;
		if(HttpContans.CONTENT_TYPE_JSON.equals(contentType)){
			entityString = postRequest.getBodyData();
		}else if(HttpContans.CONTENT_TYPE_XML.equals(contentType)){
			
		}else if(HttpContans.CONTENT_TYPE_MAP.equals(contentType)){
			entityString = map2KeyValueString(postRequest.getBodyParams());
		}
		
		if(null != entityString){
			entity = new StringEntity(entityString,HttpContans.CHARSET_GBK);
			//服务器告诉浏览器自己响应的对象的类型
			if(null != contentType){
				if(HttpContans.CONTENT_TYPE_JSON.equals(contentType)){
					//发送的参数文本格式为json格式
					entity.setContentType("application/json");
				}else if(HttpContans.CONTENT_TYPE_XML.equals(contentType)){
					//发送的参数文本格式为xml格式
					entity.setContentType("application/xml");
				}else{
					//发送的参数文本格式为?name=value&name2=value2&name3=value3格式
					entity.setContentType("application/x-www-form-urlencoded");
				}
			}
		}
		if(null != entity){
			httpPost.setEntity(entity);
		}
    	
	}

	private String map2KeyValueString(HttpParameters map) {
		if (map == null) {
			return "";
		}
		StringBuffer str = new StringBuffer("");
		Set<String> keySet = map.keySet();
		Iterator<String> it = keySet.iterator();
		while (it.hasNext()) {
			String key = it.next();
			String value = map.getAsQueryString(key);
			str.append(value + "&");
		}
		if (str.length() > 0) {
			str = str.deleteCharAt(str.length() - 1);
		}
		return str.toString();

	}
	
	private HttpClient getHttpClient() {
		SchemeRegistry schemeRegistry = new SchemeRegistry();
		schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

		HttpParams localHttpParams = new BasicHttpParams();
		HttpConnectionParams.setConnectionTimeout(localHttpParams, HttpConnectConfig.getConnectTimeOut());
		HttpConnectionParams.setSoTimeout(localHttpParams, HttpConnectConfig.getSocketTimeOut());

		ThreadSafeClientConnManager tsccm = new ThreadSafeClientConnManager(localHttpParams, schemeRegistry);
		
		HttpClient client = new DefaultHttpClient(tsccm, localHttpParams);
		client.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY, httpHost);
		return client;
	}
	
	
}
